package com.ibeetl.cms.service;

import com.ibeetl.admin.core.entity.CoreFunction;
import com.ibeetl.admin.core.rbac.tree.CatalogItem;
import com.ibeetl.admin.core.service.CoreBaseService;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.enums.DelFlagEnum;
import com.ibeetl.cms.dao.CmsCatalogDao;
import com.ibeetl.cms.entity.CmsCatalog;
import org.beetl.sql.core.engine.PageQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述: 栏目 service，包含常规栏目和级联栏目的操作。
 * @author : xiandafu
 */
@Service
@Transactional
public class CmsCatalogService extends CoreBaseService<CmsCatalog> {

    private static final Logger LOGGER = LoggerFactory.getLogger(CmsCatalogService.class);

    @Autowired
    private CmsCatalogDao catalogDao;

    @Autowired
    CorePlatformService platformService;
    
    @Autowired
    CmsCatalogService self ;

    /**
     * 根据类型获取栏目集合
     * @param type 栏目类型，
     * @return List
     */
    @Cacheable(value = CorePlatformService.CATALOG_CACHE_TYPE)
    public List<CmsCatalog> findAllByType(String type) {
        return catalogDao.findAllList(type);
    }
    
    /**
     * 级联栏目查询，必须提供一个栏目类型
     * @param value
     * @return
     */
    @Cacheable(value = CorePlatformService.CATALOG_CACHE_CHILDREN)
    public List<CmsCatalog> findAllByGroup(String type, String value) {
       List<CmsCatalog> list = self.findAllByType(type);
       return  _search(list,value);
        
    }
    
    /**
     * 级联字段下一级的字段列表
     * @return
     */
    @Cacheable(value = CorePlatformService.CATALOG_CACHE_CHILDREN)
    public List<CmsCatalog> findChildByParent(Long id) {
        return catalogDao.findChildByParent(id);
    }

    @Cacheable(value = CorePlatformService.CATALOG_CACHE_VALUE)
    public CmsCatalog findCoreCatalog(String type, String value) {
       List<CmsCatalog> list = self.findAllByGroup(type, value);
       if(list==null) {
           return null;
       }
       for(CmsCatalog catalog:list) {
           if(catalog.getId().equals(value)) {
               return catalog;
           }
       }
 	  
 	   return null;
    }
    
    /*通过名字反向查找数据栏目，通常用于excel导入*/
    public Map<String, CmsCatalog> mapCatalogByName(String type){
        List<CmsCatalog> list = self.findAllByType(type);
        Map<String, CmsCatalog> map = new HashMap<String, CmsCatalog>();
        for(CmsCatalog catalog:list) {
            map.put(catalog.getName(), catalog);
        }
        return  map;
    }
    
   
    
   /*递归查找*/ 
    private List<CmsCatalog> _search(List<CmsCatalog> list, String value) {
        for(CmsCatalog catalog:list) {
            if(catalog.getId().equals(value)) {
                return list;
            }else {
                List<CmsCatalog> children = findChildByParent(catalog.getId());
                if(children.isEmpty()) {
                    continue;
                }else {
                    List<CmsCatalog> ret = _search(children,value);
                    if(ret!=null) {
                        return ret;
                    }
                }
                
            }
        }
        return null;
    }

   
    /**
     * 查询字段类型列表
     * @return
     */
    public List<Map<String, String>> findTypeList() {
        return catalogDao.findTypeList(DelFlagEnum.NORMAL.getValue());
    }

    public PageQuery<CmsCatalog> queryByCondition(PageQuery query) {
        catalogDao.queryByCondition(query);
        queryListAfter(query.getList());
        return query;
    }


    public void queryByCondtion(PageQuery<CmsCatalog> query) {
        catalogDao.queryByCondtion(query);
        queryListAfter(query.getList());
    }

    public Long saveCatalog(CmsCatalog catalog) {
        catalogDao.insert(catalog, true);
        platformService.clearCatalogCache();
        return catalog.getId();
    }

    public void deleteCatalog(Long catalogId) {
        deleteCatalogId(catalogId);
    }

    public void batchDeleteCatalogId(List<Long> catalogIds) {
        for (Long id : catalogIds) {
            deleteCatalogId(id);
        }
        platformService.clearCatalogCache();
    }

    public void updateCatalog(CmsCatalog catalog) {
        catalogDao.updateById(catalog);
        platformService.clearCatalogCache();
    }

    public CmsCatalog getCatalog(Long catalogId) {
        CmsCatalog catalog = catalogDao.unique(catalogId);
        platformService.clearCatalogCache();
        return catalog;
    }


    private void deleteCatalogId(Long catalogId) {
        CatalogItem root = platformService.buildCatalog();
        CatalogItem fun = root.findChild(catalogId);
        if (fun != null) {//当删除栏目进行全选时，会出现父栏目和子栏目都选中的情况，这时，由于迭代时，先删除父类的时候，会把父类下的子类一起删除，造成迭代到要删除子类时，子类已经没有了。会报空指针异常
            List<CatalogItem> all = fun.findAllItem();
            //也删除自身
            all.add(fun);
            realDeleteCatalog(all);
        }
    }

    private void realDeleteCatalog(List<CatalogItem> all) {
        List<Long> ids = new ArrayList<>(all.size());
        for (CatalogItem item : all) {
            ids.add(item.getId());
            this.catalogDao.deleteById(item.getId());
        }

    }

    public CoreFunction getArticleListFunctionFromCatalogId(Long catalogId) {
        return this.catalogDao.getArticleListFunctionFromCatalogId(catalogId);
    }

    public CmsCatalog getCatalogByCode(String code) {
        return this.catalogDao.getCatalogByCode(code);
    }
  
}
